import random
from logging import getLogger
from django.http import HttpResponse, JsonResponse
from django.shortcuts import render
from django_redis import get_redis_connection

from celery_tasks.sms.tasks import send_sms_code
from meiduo.utils.mei_duo import TimeOp
from users.models import User
from . import constants
from .libs.captcha.captcha import captcha

logger = getLogger('django')


def code_img(request, uuid):
    """图片验证码"""

    code, img = captcha.generate_captcha()

    redis_conn = get_redis_connection('verify')
    redis_conn.setex(name='img_%s' % uuid, value=code, time=constants.IMG_EXPIRE_TIME)

    logger.info("[UUID: %s][验证码：%s] 发送图片验证码[成功]" % (uuid, code))

    return HttpResponse(img, content_type='image/jpg')
    # return HttpResponse(code)   # 测试用


def code_sms(request, uuid, code_img, mobile):
    """发送短信验证码"""

    # 校验图片验证码
    redis_conn = get_redis_connection('verify')
    pl = redis_conn.pipeline()  # redis管道
    code_db = redis_conn.get('img_%s' % uuid)
    if code_db is None:
        return JsonResponse({'code': 401, 'errmsg': '图片验证码已失效'},
                            json_dumps_params={"ensure_ascii": False})

    # 值不为空，先从数据库中删除，再解码比较小写
    redis_conn.delete('img_%s' % uuid)
    if code_img.lower() != code_db.decode().lower():
        return JsonResponse({'code': 401, 'errmsg': '图片验证码错误'},
                            json_dumps_params={"ensure_ascii": False})

    # 限流，禁止频繁地发送请求
    if redis_conn.get('flag_%s' % mobile):
        return JsonResponse({'code': 402, 'errmsg': '禁止频繁发送'},
                            json_dumps_params={"ensure_ascii": False})

    # 限制单位时间内的发送次数
    count = redis_conn.get('count_%s' % mobile)
    time = redis_conn.ttl('count_%s' % mobile)
    if count:
        count = int(count.decode())
        if count >= constants.SMS_SEND_COUNT:
            return JsonResponse({'code': 402,
                                 'errmsg': '当前手机号的发送次数已用完，请%s后再发送' % TimeOp.s2ms(time)},
                                json_dumps_params={"ensure_ascii": False})
        pl.setex(name='count_%s' % mobile, value=count + 1, time=time)
    else:
        pl.setex(name='count_%s' % mobile, value=1,
                 time=constants.SMS_SEND_UNIT_TIME)
    # 设置发送间隔
    pl.setex(name='flag_%s' % mobile, value=1,
             time=constants.SMS_SEND_INTERVAL)

    # 检查短信验证码是否过期
    time = redis_conn.ttl('mobile_%s' % mobile)
    if time >= 180:
        sms_code = redis_conn.get('mobile_%s' % mobile).decode()
    else:
        # 生成短信验证码并保存
        sms_code = ''.join(['%s' % random.randint(0, 9) for i in range(6)])
        time = constants.SMS_EXPIRE_TIME
        pl.setex(name='sms_%s' % mobile, value=sms_code,time=time)
    # 保存到Redis
    pl.execute()

    # 发送短信验证码
    time = TimeOp.s2ms(time)
    # celery 异步发送短信
    send_sms_code.delay(mobile, sms_code, time)

    return JsonResponse({'code': 200, 'errmsg': '短信验证码已发送'},
                        json_dumps_params={"ensure_ascii": False})
